#ifndef _DEV_H_
#define _DEV_H_

#include "types.h"
#include "queue.h"
#include "err.h"

typedef enum
{
   DEVICE_TYPE_SHMEM,
   DEVICE_TYPE_NETWORK_SOCKET,
   DEVICE_TYPE_FILE,
   DEVICE_TYPE_MAX
}dev_type_t;


typedef enum
{
  DEVICE_MODE_READ = 1,
  DEVICE_MODE_WRITE = 2,
}dev_permissions_t;

typedef enum
{
  DEVICE_MODE_CREATE_ALWAYS,
  DEVICE_MODE_CREATE_IF_NOT_FOUND,
  DEVICE_MODE_OPEN_EXISTING,
  DEVICE_OPEN_MODE_MAX
}dev_open_mode_t;

/*
* subtypes for NETWORK devices
*/
#define DEVICE_SUBTYPE_IP_SOCKET 1
#define DEVICE_SUBTYPE_TCP_SOCKET 2
#define DEVICE_SUBTYPE_UDP_SOCKET 3

/*
* SHMEM devices
*/
#define SHMEM_MAX_SIZE  10240   // 10 kb

/*
* device info structure
* Contains parameters to identify a device
* 
* name: Name of the device.
*       Kernel assigned name if its a fixed device
*       User assigned name if the device is created
*          by the user, like shmem, sockets etc.
*
* type: Type of device. Check dev_type_t
* subtype: Finer granularity of type
*
* address: Address of the device
* size: Size of the device address space (if applicable)
*
*/
typedef struct
{
    const uint8_t          *name;

    dev_type_t          type;     // refer dev_type_t
    uint8_t             subtype; 

    uint32_t            address;
    uint32_t            size;

}dev_info_t;

/*
* device access structure
* Contains parameters for accessing devices for create/close
*/
typedef struct
{
    void                 *dev_ptr;   //  Pointer to dev_t maintained by kernel
    uint32_t             permissions;
 }dev_access_t;

/*
* Handle to the device
* Used by the user process to access/reference the device
* in kernel/user operations
*/
typedef struct
{
    dev_info_t        dev_info;
    dev_open_mode_t   open_mode;
    dev_access_t      access_info;
    void              *pcb_ptr;   // Pointer to device entry in PCB

    q_id_t             qid;
    bool              device_created;
    err_t             err_code;  // updated by kernel while opening/closing the device
}dev_handle_t;

typedef struct
{
  dev_info_t         dev_info;
  enq_msg_t          msg;
}dev_post_msg_t;



#endif
